/**
 * Trabalho 3 de Programacao Concorrente.
 * Prof. Dr. Julio Estrella
 * 
 * Resolucao de sistemas lineares.
 * 
 * Grupo 07 - Turma B
 * Fabio de Albuquerque Dela Antonio 6792558
 * Leonardo Henrique Omoto 6793160
 * Pedro Paulo Canto Martucci 6793100
 * 
 * jacobi.c
 */

#include <geral.h>
#include <matrix.h>
#include <jacobi.h>

/**
 * Valor absoluto
 */
double dabs(double a) {
    return (a < 0) ? (-1.0f)*a : a;
}

/**
 * Confere o Erro para o metodo Jacobi-Richardson
 */
double erroJacobi(double * k_mais_um, double * k, int tam) {
    
    int i;
    double aux = 0.0f;
    double dif = 0.0f;
    
    /* Encontra maior erro */
    for(i = 0; i < tam; i++) {
        
        /*if(dabs(k_mais_um[i]) != 0.0f)
            aux = dabs((k_mais_um[i] - k[i])/k_mais_um[i]);*/
        
        aux = dabs(k_mais_um[i] - k[i]);

        if(dif < aux)
            dif = aux;
    }
    
    return dif;
}

/**
 * Calcula uma iteracao do JacobiRichardson
 */
void jacobiRichardson(Sist * sis, double * k, double * k_anterior, int var_inicial, int var_final) {
    
    if(var_final > sis->J_ORDER || var_inicial > sis->J_ORDER || var_final <= 0 || var_inicial < 0) {
        fprintf(stderr, "Valores invalidos para intervalos.\n");
        exit(1);
    }
    
    double aux;
    
    int i, j;
    
    /* Itera nas linhas do intervalo (so resolve para estas variaveis) */
    for(i = var_inicial; i < var_final; i++) {
    
        aux = 0.0f;
        
        for(j = 0; j < i; j++)
            aux += k_anterior[j] * sis->matrix[i][j];
        
        for(j = i + 1; j < sis->J_ORDER; j++)
            aux += k_anterior[j] * sis->matrix[i][j];
        
        k[i - var_inicial] = (sis->matrix[i][sis->J_ORDER] - aux) / sis->matrix[i][i];  

    }
}

